package util;


import java.nio.ByteBuffer;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 数据运算工具类
 * @author	David
 *
 */

public class DataUtils {

	/**
	 * 计算异或和
	 * @param pack
	 * @return
	 */
	public static byte check(byte[] pack){
		byte sum = 0;
		for(int i=0;i<pack.length;i++)
		{
			sum = (byte) (sum^pack[i]);
		}
		return sum;
	}
	
	/**
	 * 计算16位累加和
	 * @return
	 */
	public static int checkSum(byte[] pack){
		int sum = 0;
		for(int i=0;i<pack.length;i++){
			sum = (int)(sum+(pack[i]&0xff));
		}
		return sum;
	}
	
	/**
     * short到byte[]
     * @param i
     * @return
     */
    public static byte[] shortToByteArray(short i) {   
          byte[] result = new byte[2];   
          //由高位到低位
          result[0] = (byte)((i >> 8) & 0xFF); 
          result[1] = (byte)(i & 0xFF);
          return result;
    }
    
    /**
     * byte[]转short
     * @param bytes
     * @return
     */
    public static short byteArrayToShort(byte[] bytes) {
           short value= 0;
           if(bytes!=null && bytes.length!=0){
               //由高位到低位
               for (int i = 0; i < 2; i++) {
                   int shift= (2 - 1 - i) * 8;
                   value +=(bytes[i] & 0x000000FF) << shift;//往高位游
               }
           }

           return value;
     }
	
	/**
     * int到byte[],返回的是一个4字节的数组
     * @param i
     * @return
     */
    public static byte[] intToByteArray(int i) {   
          byte[] result = new byte[4];   
          //由高位到低位
          result[0] = (byte)((i >> 24) & 0xFF);
          result[1] = (byte)((i >> 16) & 0xFF);
          result[2] = (byte)((i >> 8) & 0xFF); 
          result[3] = (byte)(i & 0xFF);
          return result;
    }
    
    /**
     * byte[]转int
     * @param bytes
     * @return
     */
    public static int byteArrayToInt(byte[] bytes) {
           int value= 0;
           if(bytes!=null && bytes.length!=0){
               //由高位到低位
               for (int i = 0; i < 4; i++) {
                   int shift= (4 - 1 - i) * 8;
                   value +=(bytes[i] & 0x000000FF) << shift;//往高位游
               } 
           }

           return value;
     }
    
    
    /**
     * 将long类型的数字转为一个8字节的数组
     * @param x
     * @return
     */
    public static byte[] longToByteArray(long x) {  
    	ByteBuffer buffer = ByteBuffer.allocate(8);
        buffer.putLong(0, x);  
        return buffer.array();  
    }
    
    /**
     * 将一个8字节的数组转为long类型的数字
     * @param bytes
     * @return
     */
    public static long byteArrayToLong(byte[] bytes) {  
    	ByteBuffer buffer = ByteBuffer.allocate(8);
        buffer.put(bytes, 0, bytes.length);  
        buffer.flip();//need flip   
        return buffer.getLong();  
    }


	/**
	 * 获取byte数组
	 * @param src
	 * @param begin
	 * @param count
	 * @return
	 */
	public static byte[] subBytes(byte[] src, int begin, int count) {
		byte[] bs = new byte[count];
		for (int i=begin; i<begin+count; i++) bs[i-begin] = src[i];
		return bs;
	}
	
	/**
	 * byte数组转16进制形式的字符串
	 * @param b
	 * @return
	 */
	public static String byte2HexStr(byte[] b) {
	    String hs = "";  
	    String stmp = "";  
		if(b!= null&&b.length!=0){
		    for (int n = 0; n < b.length; n++) {  
		        stmp = (Integer.toHexString(b[n] & 0XFF));  
		        if (stmp.length() == 1)  
		            hs = hs + "0" + stmp;  
		        else  
		            hs = hs + stmp;  
		        hs+=" ";       
		    } 
		}
	    return hs.toUpperCase();  
	}
	
	/**
	 * byte数组转10进制字符串
	 * @param b
	 * @return
	 */
	public static String byte2Str(byte[] b) {
	    String hs = "";  
	    String stmp = "";  
		if(b!= null){
		    for (int n = 0; n < b.length; n++) {  
		        stmp = (Integer.toString(b[n] & 0XFF));  
		        
		        if (stmp.length() == 1)  
		            hs = hs + "0" + stmp;  
		        else  
		            hs = hs + stmp;  
		        hs+=" ";       
		    } 
		}
	    return hs.toUpperCase();  
	}
	
	
	
	/**
	 * 把字符串转成byte数组
	 * string有封装好的getBytes方法！
	 * @param str
	 * @return
	 */
//	public static byte[] convertStr2Byte(String str){
//		byte[] messageInt = null;
//		if(str!=null&&str.length()!=0){
//			char[] message = str.toCharArray();
//			messageInt = new byte[message.length];
//			for(int i=0;i<message.length;i++){
//				messageInt[i] = (byte)message[i];
//			}
//		}
//
//		return messageInt;
//	}
	
	
	
	/**
	 * 字符串转16进制
	 * @param str
	 * @return
	 */
	public static String convertStringToHex(String str){

		char[] chars = str.toCharArray();
		
		StringBuffer hex = new StringBuffer();
		for(int i = 0; i < chars.length; i++){
		  hex.append(Integer.toHexString(chars[i]));
		}
		
		return hex.toString();
	 }
	
	/**
	 * 16进制转字符串
	 * @param hex
	 * @return
	 */
	public String convertHexToString(String hex){
	
		StringBuilder sb = new StringBuilder();
		StringBuilder temp = new StringBuilder();
	
		//49204c6f7665204a617661 split into two characters 49, 20, 4c...
		for( int i=0; i<hex.length()-1; i+=2 ){
	
			//grab the hex in pairs
			String output = hex.substring(i, (i + 2));
			//convert hex to decimal
			int decimal = Integer.parseInt(output, 16);
			//convert the decimal to character
			sb.append((char)decimal);
	
			temp.append(decimal);
		}
	
		return sb.toString();
	}
	
	/**
	 * 将1970年至今的秒数，转成日期
	 * @return
	 */
	public static String second2Date(long second){
//		long sd=1345185923140L;
		long time = (long)second*1000;
        Date dat=new Date(time);  
        GregorianCalendar gc = new GregorianCalendar();   
        gc.setTime(dat);  
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String sb=format.format(gc.getTime());  

        return sb;
        
	}
	
	/**
	 * 将1970年至今的4字节或者6字节的byte数组(秒数)转成日期
	 * @return
	 */
	public static String byteArray2Date(byte[] b){
//		long sd=1345185923140L;
		long second = DataUtils.byteArrayToLong(DataUtils.cutByteArray(b, 8));
		long time = second*1000;
        Date dat=new Date(time);  
        GregorianCalendar gc = new GregorianCalendar();   
        gc.setTime(dat);  
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String sb=format.format(gc.getTime());  

        return sb;
        
	}


	/**
	 * 将1970年至今的4字节或者6字节的byte数组(秒数)转成日期
	 * @return
	 */
	public static String byteArrayToDate(byte[] b){
//		long sd=1345185923140L;
		long second = DataUtils.byteArrayToLong(DataUtils.cutByteArray(b, 8));
		long time = second*1000;
		Date dat=new Date(time);
		GregorianCalendar gc = new GregorianCalendar();
		gc.setTime(dat);
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
		String sb=format.format(gc.getTime());

		return sb;

	}


	/**
	 * 将时间格式：yyyy-MM-dd HH:mm:ss  格式化为：yyyyMMddhhmmss
	 * @param time yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static String getTime(String time){
		try {
			SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			SimpleDateFormat newformat=new SimpleDateFormat("yyyyMMddHHmmss");
			return newformat.format(format.parse(time));
		}catch (Exception e){
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 标准时间字符串"yyyy-MM-dd hh:mm:ss" 转成毫秒数
	 * @param date
	 * @return
	 * @throws ParseException 
	 */
	public static long DateStr2Msec(String date) throws ParseException{
		SimpleDateFormat formatter=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date d = formatter.parse(date);
		
		return d.getTime();
	}
	
	/**
	 * 将zd的日期byte数组转为1970年至今的毫秒数
	 * @param b
	 * @return
	 */
	public static long byteArray2Msec(byte[] b){
		long second = DataUtils.byteArrayToLong(DataUtils.cutByteArray(b, 8));
		return second*1000;
	}
	
	/**
	 * 当前时间 转成4字节的byte数组
	 * @param 
	 * @return
	 */
	public static byte[] currentDate2Byte(){
//		long sd=1345185923140L;
		long sencond = System.currentTimeMillis()/1000;
		byte[] time = DataUtils.longToByteArray(sencond);
		
        return DataUtils.cutByteArray(time, 4);
        
	}
	
	/**
	 * 截取一个字符数组，留低位，截后长度为n；如果数组不够长，前面补0；
	 * @return
	 */
	public static byte[] cutByteArray(byte[] b,int n){
		byte[] b1 = new byte[n];
		if(b!=null){
			if(b.length<n){
				System.arraycopy(b, 0, b1, n-b.length, b.length);
				return b1;
			}else if(b.length>n){
				System.arraycopy(b, b.length-n, b1, 0, b1.length);
				return b1;
			}else{
				return b;
			}
		}else{
			return b1;
		}

		
	}
	
	/**
	 * 将byte数组转成ascii字符串
	 * @param b
	 * @return
	 */
	public static String byteArray2Ascii(byte[] b){
		StringBuffer sb = null;
		if(b!=null&&b.length!=0){
			sb = new StringBuffer();
			for(int i=0;i<b.length;i++){
				sb.append((char)(b[i]));
			}
			return sb.toString().trim();
		}else{
			return "";
		}
		
	}
	
	 /** 
     * 将byte转换为一个长度为8的byte数组，数组每个值代表bit 
     */  
    public static byte[] getBooleanArray(byte b) {  
        byte[] array = new byte[8];  
        for (int i = 7; i >= 0; i--) {  
            array[i] = (byte)(b & 1);  
            b = (byte) (b >> 1);  
        }  
        return array;  
    }
    
    /**
     * 将格式为192。168.1.1:8080的字符串，转化为byte数组。
     * @param s
     * @return
     */
    public static byte[] StrIP2ByteArray(String s){
    	byte[] ipByte = new byte[6];	
    	if(s!=null&&s.length()!=0){
        	String[] str = s.split(":");
        	String[] str1 = str[0].split("\\.");
        	
        	for(int i=0;i<str1.length;i++){
//        		ipByte[i] = DataUtils.cutByteArray(DataUtils.intToByteArray(Integer.valueOf(str1[i])), 1)[0];
        		ipByte[i] = (byte)(Integer.valueOf(str1[i])&0xff);
        	}
        	byte[] port = DataUtils.cutByteArray(DataUtils.intToByteArray(Integer.valueOf(str[1])), 2);
        	System.arraycopy(port, 0, ipByte, 4, 2);
    	}

    	return ipByte;
    	
    }
    
    /**
     * 将格式为192。168.1.1的字符串，转化为byte数组。(ip不含端口)
     * @param s
     * @return
     */
    public static byte[] IP2ByteArray(String s){
    	byte[] ipByte = new byte[4];	
    	if(s!=null&&s.length()!=0){
        	String[] str = s.split("\\.");
        	
        	for(int i=0;i<str.length;i++){
//        		ipByte[i] = DataUtils.cutByteArray(DataUtils.intToByteArray(Integer.valueOf(str1[i])), 1)[0];
        		ipByte[i] = (byte)(Integer.valueOf(str[i])&0xff);
        	}
    	}

    	return ipByte;
    	
    }
    
    /**  
     * @功能: BCD码转为10进制串(阿拉伯数据)  
     * @参数: BCD码  
     * @结果: 10进制串  
     */  
    public static String bcd2Str(byte[] bytes) {  
        StringBuffer temp = new StringBuffer(bytes.length * 2);  
        for (int i = 0; i < bytes.length; i++) {  
            temp.append((byte) ((bytes[i] & 0xf0) >>> 4));  
            temp.append((byte) (bytes[i] & 0x0f));  
        }  
//        return temp.toString().substring(0, 1).equalsIgnoreCase("0") ? temp  
//                .toString().substring(1) : temp.toString();
        return temp.toString();
    }
    
    /**  
     * @功能: BCD码转为10进制串数组(阿拉伯数据)  
     * @参数: BCD码  
     * @结果: 10进制串  
     */  
    public static String[] bcd2StrArray(byte[] bytes) {  
        StringBuffer temp = new StringBuffer(bytes.length * 2);  
        for (int i = 0; i < bytes.length; i++) {  
            temp.append((byte) ((bytes[i] & 0xf0) >>> 4));  
            temp.append((byte) (bytes[i] & 0x0f));
            temp.append(" ");
        }  
//        return temp.toString().substring(0, 1).equalsIgnoreCase("0") ? temp  
//                .toString().substring(1) : temp.toString();
        return temp.toString().split(" ");
    }
    
    /**  
     * @功能: 10进制串转为BCD码  
     * @参数: 10进制串  
     * @结果: BCD码  
     */  
    public static byte[] str2Bcd(String asc) {  
        int len = asc.length();  
        int mod = len % 2;  
        if (mod != 0) {  
            asc = "0" + asc;  
            len = asc.length();  
        }  
        byte abt[] = new byte[len];  
        if (len >= 2) {  
            len = len / 2;  
        }  
        byte bbt[] = new byte[len];  
        abt = asc.getBytes();  
        int j, k;  
        for (int p = 0; p < asc.length() / 2; p++) {  
            if ((abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {  
                j = abt[2 * p] - '0';  
            } else if ((abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {  
                j = abt[2 * p] - 'a' + 0x0a;  
            } else {  
                j = abt[2 * p] - 'A' + 0x0a;  
            }  
            if ((abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {  
                k = abt[2 * p + 1] - '0';  
            } else if ((abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {  
                k = abt[2 * p + 1] - 'a' + 0x0a;  
            } else {  
                k = abt[2 * p + 1] - 'A' + 0x0a;  
            }  
            int a = (j << 4) + k;  
            byte b = (byte) a;  
            bbt[p] = b;  
        }  
        return bbt;  
    }  



	public static String getHour(){
		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHH");

		Date date = new Date();

		return formatter.format(date);
	}


	/**
	 * java 中 short取值范围：-32768~32768；int 取值范围：  明天： long类型的数字转成4位byte数组。？？？？
	 * 将byte[]数组转为int类型的正数。
	 */
//	public static int byteArray2unsignedNum(byte[] b){
//        int x = 0;
//        String s = DataUtils.binary(b, 2);
//        for(char c: s.toCharArray())
//             x = x * 2 + (c == '1' ? 1 : 0);
//        return x;
//	}
	
	
    /** 
     * 将byte[]转为各种进制的字符串 
//     * @param bytes byte[]
//     * @param radix 基数可以转换进制的范围，从Character.MIN_RADIX到Character.MAX_RADIX，超出范围后变为10进制
     * @return 转换后的字符串 
     */  
//    public static String binary(byte[] bytes, int radix){  
//        return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数  
//    }
    
 

	/**
	 * "00 01 02"->>{0x00,0x01,0x02} 
	 */
	public static byte[] hexStr2ByteArray(String str){
		String[] strList = str.split(" ");
		byte[] byteList = new byte[strList.length];
		for(int i=0;i<strList.length;i++){
			byteList[i] = (byte) Integer.parseInt(strList[i], 16);
		}
		return byteList;
		
	}



	/**
	 * byte:-1 --> int:255,获得byte的无符号数值。
	 * @param b
	 * @throws Exception
	 */
	public static Integer byte2unsignedInt(byte b){
		int unsignedInt = (int)(b&0xff);
		return unsignedInt;
	}
	
	
    
	public static void main(String[] args) throws Exception {

		byte[] bytes=new byte[]{(byte)0x56,(byte)0x33,(byte)0x66,(byte)0x9F};
//		byte[] bytes=new byte[]{0x56, 0x2F, 0x1D, 0x55};
		System.out.println(DataUtils.byteArray2Date(bytes));


		byte[] time=new byte[]{-1, -1, -1, -1, -121, -29, -8, -82};
		System.out.println(DataUtils.byteArrayToLong(time));

		System.out.println(DataUtils.DateStr2Msec("2018-12-31 23:59:59")+8 *60 *60*1000);
		System.out.println(new Date(DataUtils.DateStr2Msec("2018-12-31 23:59:59")+8 *60 *60*1000));

	}
    
    
}
